package com.zeus.core.report;

import com.zeus.common.enums.ZeusEventTypeEnum;
import com.zeus.common.utils.StackTraceUtils;
import com.zeus.core.open.event.ZeusEvent;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;

import java.util.Optional;

/**
 * Log4j上报工具
 *
 * @author f1ybear_wang  2022/2/22 7:50 下午
 */
public class ZeusReportLog4jClient extends AbstractLogZeusReportClient {

    /**
     * 日志信息
     */
    private LoggingEvent loggingEvent;

    public ZeusReportLog4jClient(LoggingEvent loggingEvent) {
        super();
        this.loggingEvent = loggingEvent;
        this.zeusEvent = ZeusEvent.builder().eventType(eventType()).message(loggingEvent.getRenderedMessage()).build();
    }

    @Override
    public ZeusEventTypeEnum eventType() {
        return ZeusEventTypeEnum.LOG4J_EVENT;
    }

    @Override
    protected void parsingExtend() {
        if (this.parsingExtendInit || this.loggingEvent == null) {
            return;
        }
        // 初始化基础数据
        this.message = this.loggingEvent.getRenderedMessage();
        this.loggerName = this.loggingEvent.getLoggerName();
        this.occurrenceTime = this.loggingEvent.getTimeStamp();
        // 初始化文件名、方法名、行号
        LocationInfo locationInfo = this.loggingEvent.getLocationInformation();
        if (locationInfo != null) {
            this.fileName = locationInfo.getFileName();
            this.methodName = locationInfo.getMethodName();
            this.lineNumber = locationInfo.getLineNumber();
        }

        // 获取异常
        Throwable ex = Optional.of(this.loggingEvent).map(LoggingEvent::getThrowableInformation)
            .map(ThrowableInformation::getThrowable).orElse(null);
        if (ex != null) {
            this.exceptionMessage = ex.getMessage();
            this.stackTrace = StackTraceUtils.getStackTrace(ex);
        }
        this.gatherRule.setAlarmLevel(this.message, this.loggerName, this.exceptionMessage, this.stackTrace);
        this.parsingExtendInit = true;
    }
}
